﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Xml.Serialization;
using Cav;

namespace Nefela.CommonTypes
{
    /// <summary>
    /// Описание поля карточки клиента
    /// </summary>
    public class FieldCardCustomerType : INotifyPropertyChanged
    {
        private String name;
        private String labeltext;
        private Boolean userinput;

        /// <summary>
        /// Описание 
        /// </summary>
        public String Name
        {
            get { return name; }
            set
            {
                if (value == name)
                    return;
                name = value;
                NotifyPropertyChanged("Name");
            }
        }
        /// <summary>
        /// Метка
        /// </summary>
        public String LabelText
        {
            get { return labeltext; }
            set
            {
                if (value == labeltext)
                    return;
                labeltext = value;
                NotifyPropertyChanged("LabelText");
            }
        }
        /// <summary>
        /// Ввод осуществляется пользователем на момент заполнения шаблона
        /// </summary>
        public Boolean UserInput
        {
            get { return userinput; }
            set
            {
                if (value == userinput)
                    return;
                userinput = value;
                NotifyPropertyChanged("UserInput");
            }
        }

        #region Члены INotifyPropertyChanged

        private void NotifyPropertyChanged(String PropertyName)
        {
            HasChanged = true;

            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public FieldCardCustomerType Clone()
        {
            var res = new FieldCardCustomerType();
            res.LabelText = this.LabelText;
            res.Name = this.Name;
            res.UserInput = this.UserInput;
            res.HasChanged = false;
            return res;
        }

        /// <summary>
        /// Наличие изменений
        /// </summary>
        [XmlIgnore]
        public Boolean HasChanged { get; set; }
    }

    /// <summary>
    /// Шаблон документа
    /// </summary>
    public class TemplateDocumentType : INotifyPropertyChanged
    {

        public TemplateDocumentType()
        {
            filetemplate = new byte[0] { };
        }

        private String name;
        private String filenameoutput;
        private byte[] filetemplate;

        /// <summary>
        /// Наименование документа
        /// </summary>
        public String Name
        {
            get { return name; }
            set
            {
                if (value == name)
                    return;
                name = value;
                NotifyPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Файл шаблона документа.
        /// </summary>
        public byte[] FileTemplate
        {
            get { return filetemplate; }
            set
            {
                if (value == filetemplate)
                    return;
                filetemplate = value;
                NotifyPropertyChanged("FileTemplate");
            }
        }

        /// <summary>
        /// Наименование выходного файла.
        /// </summary>
        public String FileNameOutput
        {
            get { return filenameoutput; }
            set
            {
                if (value == filenameoutput)
                    return;
                filenameoutput = value;
                NotifyPropertyChanged("FileNameOutput");
            }
        }

        public TemplateDocumentType Clone()
        {

            var res = new TemplateDocumentType();
            res.Name = this.Name;
            res.FileNameOutput = this.FileNameOutput;
            if (FileTemplate != null)
                res.FileTemplate = this.FileTemplate.ToArray();
            res.HasChanged = false;
            return res;
        }

        public override string ToString()
        {
            return this.Name;
        }

        #region Члены INotifyPropertyChanged

        private void NotifyPropertyChanged(String PropertyName)
        {
            HasChanged = true;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        /// <summary>
        /// Наличие изменений
        /// </summary>
        [XmlIgnore]
        public Boolean HasChanged { get; set; }
    }

    /// <summary>
    /// Пакет документов для обработки и настройки карточки клиента
    /// </summary>
    public class PackegeDocsType
    {
        public PackegeDocsType()
        {
            CardCustomer = new BindingList<FieldCardCustomerType>();
            TemplatesDocs = new BindingList<TemplateDocumentType>();
        }

        public String OutputDir { get; set; }

        public BindingList<TemplateDocumentType> TemplatesDocs { get; set; }
        /// <summary>
        /// Параметры замены меток
        /// </summary>
        public BindingList<FieldCardCustomerType> CardCustomer { get; set; }

        public void LoadFromPackege(PackegeDocsType Packege)
        {
            this.CardCustomer.Clear();
            this.TemplatesDocs.Clear();

            this.CardCustomer.AddRange(Packege.CardCustomer);
            this.TemplatesDocs.AddRange(Packege.TemplatesDocs);
        }

        public String AddFieldCardCustomer(FieldCardCustomerType NewField)
        {
            NewField.Name = NewField.Name.Trim2();
            if (NewField.Name.IsNullOrWhiteSpace())
                return "Необходимо заполнить имя поля";
            NewField.LabelText = NewField.LabelText.Trim2();
            if (NewField.LabelText.IsNullOrWhiteSpace())
                return "Необходимо заполнить метку поля";
            if (CardCustomer.Any(x => x.Name == NewField.Name))
                return "Поле с таким именем уже есть";
            if (CardCustomer.Any(x => x.LabelText == NewField.LabelText))
                return "Поле с такой меткой уже есть";
            CardCustomer.Add(NewField);
            return null;
        }

        public String AddTemplateDocs(TemplateDocumentType NewTDoc)
        {
            NewTDoc.Name = NewTDoc.Name.Trim2();
            if (NewTDoc.Name.IsNullOrWhiteSpace())
                return "Необходимо заполнить имя документа";
            NewTDoc.FileNameOutput = NewTDoc.FileNameOutput.Trim2();
            if (NewTDoc.FileNameOutput.IsNullOrWhiteSpace())
                return "Необходимо заполнить имя файла документа";
            if (TemplatesDocs.Any(x => x.Name == NewTDoc.Name))
                return "Шаблон с таким именем уже есть";
            if (TemplatesDocs.Any(x => x.FileNameOutput == NewTDoc.FileNameOutput))
                return "Шаблон с таким именем файла уже есть";
            if (NewTDoc.FileTemplate == null || NewTDoc.FileTemplate.Length == 0)
                return "Необходимо добавить файл шаблона";
            TemplatesDocs.Add(NewTDoc);
            return null;
        }

        public Boolean HasChanged
        {
            get
            {
                return this.CardCustomer.Any(x => x.HasChanged) || this.TemplatesDocs.Any(x => x.HasChanged);
            }

            set
            {
                foreach (var item in this.TemplatesDocs)
                    item.HasChanged = value;
                foreach (var item in this.CardCustomer)
                    item.HasChanged = value;
            }
        }
    }

    /// <summary>
    /// Поле карточки
    /// </summary>
    public class FieldCardType : INotifyPropertyChanged
    {
        public FieldCardType()
        {
        }

        [XmlIgnore]
        public FieldCardCustomerType FieldCardCustomer { get; set; }

        private string name;
        private string replacementText;

        /// <summary>
        /// Ссылка на имя поля
        /// </summary>
        public String Name
        {
            get
            {
                return name;
            }
            set
            {
                if (value == name)
                    return;
                name = value;
                NotifyPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Текст замены
        /// </summary>
        public String ReplacementText
        {
            get
            {
                return replacementText;
            }
            set
            {
                if (value == replacementText)
                    return;
                replacementText = value;
                NotifyPropertyChanged("ReplacementText");
            }
        }
        /// <summary>
        /// Заполнено ли поле ReplacementText. 
        /// Проверка для ругалки.
        /// </summary>
        /// <returns></returns>
        public Boolean CheckReplasmentText()
        {
            return !(FieldCardCustomer != null && !FieldCardCustomer.UserInput && this.ReplacementText.IsNullOrWhiteSpace());
        }

        #region Члены INotifyPropertyChanged

        private void NotifyPropertyChanged(String PropertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    }

    /// <summary>
    /// Карточка клиента
    /// </summary>
    public class CustomerCardType : INotifyPropertyChanged
    {
        public CustomerCardType()
        {
            Fields = new BindingList<FieldCardType>();
        }

        private string name;

        /// <summary>
        /// Наименование карточки
        /// </summary>
        public String Name
        {
            get
            {
                return name;
            }
            set
            {
                if (value == name)
                    return;
                name = value;
                NotifyPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Поля карточки
        /// </summary>
        public BindingList<FieldCardType> Fields { get; set; }

        /// <summary>
        /// Проверка корректности заполненности карточки
        /// Чтоб ругнуться, если что.
        /// </summary>
        /// <returns></returns>
        public Boolean CheckCard()
        {
            return !Fields.Any(x => !x.CheckReplasmentText());
        }

        #region Члены INotifyPropertyChanged

        private void NotifyPropertyChanged(String PropertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

    /// <summary>
    /// коллекция с карточками
    /// </summary>
    public class CustomerCardsColection : BindingList<CustomerCardType>
    {

    }

}
